class LineManager {
	private constructor() {
	}
	private static instance: LineManager;
	public static getInstance() {
		if (this.instance == null) {
			this.instance = new LineManager();
		}
		return this.instance;
	}

	private userMgr = AIUserMgr.getInstance();

	private util = Util.getInstance();

	private linesPool = [];

	private totallinesPool = 0;

	private c = serverConfig.config;

	//++++++++++roommgr++++++++++++++//
	//private roomLine = [];
	//判断指定的线是否还存在
	public checklines(users, room) {
		var roomLine = room.roomLine;
		//判断所有的线是否存在
		this.checkLinesAlive(roomLine);
		//判断是否有新的线的产生
		this.createNewLines(room.roomUser, room);
		return roomLine;
	}
	/**
	 * 创建新的线
	 * @param {*} users
	 */
	private createNewLines(users, room) {
		for (var t = 0; t < users.length; t++) {
			if (users[t].userId != -1 && !users[t].death.isDeath) {
				if (this.alreadyExistLine(users[t].userId, room)) {
					if (users[t].death.isDeath || users[t].ishadLine)
						continue;
					// if (users[t].propStates.getPropType == 3)
					// 	continue;
					if (users[t].disconnection_line)
						continue;
					if (this.c.isLineAutoConnect) {
						this.checkUserHadLine(users[t], users, room);
					}
				}
			}
		}
	}
	private alreadyExistLine(id, room) {
		for (var t = 0; t < room.roomLine.length; t++) {
			if (room.roomLine[t].userOneId == id || room.roomLine[t].userTwoId == id) {
				//已经和青蛙相连的青蛙创建过线
				return false;
			}
		}
		return true;
	}


	private HadLineP0tmp = new egret.Point(0, 0);
	private HadLineP1tmp = new egret.Point(0, 0);
	/**
	 * 判断玩家是否可以创建线
	 * 遍历房间内所有玩家，进行连线
	 */
	private checkUserHadLine(targetplayer, users, room) {
		var roomLine = room.roomLine;
		if (targetplayer.userId == -1) {
			return;
		}
		if (targetplayer.states != 0) {
			return;
		}
		targetplayer = this.userMgr.get(targetplayer.userId);
		if (targetplayer == null) {

			return;
		}
		/*if (targetplayer.userId == DataProl.account) {
			return;
		}*/

		/*	if (targetplayer.ishadLine) {
				//player身上ishadline不可信
				this.setIsHadLineFalse(room, targetplayer);
				if (targetplayer.ishadLine) {
					//	console.log("aaaaaa" + targetplayer.otherLineUser);
					return;
				}

			} else {
				if (targetplayer.otherLineUser != -1) {

					return;
				}
			}*/
		//判断一下两个玩家之间的距离是否是最短距离
		var minUserDistance = 10000;
		var minLineUser = null;
		var userOne, userTwo;
		for (var t = 0; t < users.length; t++) {
			if (users[t].userId == targetplayer.otherLineUser)
				continue;
			if (users[t].userId == targetplayer.userId)
				continue;
			/*if (users[t].userId == DataProl.account)
				continue;*/
			if (users[t].states != 0)
				continue;
			var nowDistance = this.util.getDistance(targetplayer, users[t]);
			//var tagetLength = targetplayer.lineLength + users[t].lineLength;
			/**遍历所有玩家 */
			if (nowDistance < 50) {
				if (nowDistance < minUserDistance) {
					minUserDistance = nowDistance;
					minLineUser = users[t];
					continue;
				}
			}

		}

		if (minLineUser != null) {
			if (minLineUser.ishadLine || targetplayer.ishadLine) {
				this.HadLineP0tmp.setTo(minLineUser.x, minLineUser.y);
				this.HadLineP1tmp.setTo(targetplayer.x, targetplayer.y);

				var point1: any = this.calulatePopDir(this.HadLineP1tmp, this.HadLineP0tmp, targetplayer.level, minLineUser.level);
				var point2: any = this.calulatePopDir(this.HadLineP0tmp, this.HadLineP1tmp, minLineUser.level, targetplayer.level);
				if (minLineUser.propStates[1].getPropType != 2) {
					//让青蛙眩晕
					AIPropsMgr.getInstance().changeSinglePlayerState({ type: 8 }, minLineUser);
					//变更服务器上青蛙位置避免一直触发碰撞
					this.frogchangepoint(minLineUser, point2)
					//获取tween动画方法
					this.getflicktween(point2, minLineUser);
				}
				if (targetplayer.propStates[1].getPropType != 2) {
					//让青蛙眩晕
					AIPropsMgr.getInstance().changeSinglePlayerState({ type: 8 }, targetplayer);
					//变更服务器上青蛙位置避免一直触发碰撞
					this.frogchangepoint(targetplayer, point1)
					//获取tween动画方法
					this.getflicktween(point1, targetplayer);
				}

				return;

			}
			else {
				if (minLineUser.frogType != targetplayer.frogType || minLineUser.disconnection_line)//判断青蛙种类是否相同
				{
					this.HadLineP0tmp.setTo(minLineUser.x, minLineUser.y);
					this.HadLineP1tmp.setTo(targetplayer.x, targetplayer.y);

					var point1: any = this.calulatePopDir(this.HadLineP1tmp, this.HadLineP0tmp, targetplayer.level, minLineUser.level);
					var point2: any = this.calulatePopDir(this.HadLineP0tmp, this.HadLineP1tmp, minLineUser.level, targetplayer.level);
					if (minLineUser.propStates[1].getPropType != 2) {
						//让青蛙眩晕
						AIPropsMgr.getInstance().changeSinglePlayerState({ type: 8 }, minLineUser);
						//变更服务器上青蛙位置避免一直触发碰撞
						this.frogchangepoint(minLineUser, point2)
						//获取tween动画方法
						this.getflicktween(point2, minLineUser);
					}
					if (targetplayer.propStates[1].getPropType != 2) {
						//让青蛙眩晕
						AIPropsMgr.getInstance().changeSinglePlayerState({ type: 8 }, targetplayer);
						//变更服务器上青蛙位置避免一直触发碰撞
						this.frogchangepoint(targetplayer, point1)
						//获取tween动画方法
						this.getflicktween(point1, targetplayer);
					}
					return;
				}
				else {
					var line = this.getOneLine(targetplayer.userId, minLineUser.userId);
					if (line == null) {
						//	console.log("dddddd" + targetplayer.otherLineUser);;
						return;
					}

					line.userOneId = targetplayer.userId;
					line.userTwoId = minLineUser.userId;

					line.isUsed = true;
					line.type = minLineUser.frogType;
					line.uop = { x: targetplayer.x, y: targetplayer.y };
					line.utp = { x: minLineUser.x, y: minLineUser.y };

					//此处因为使用的是临时生成的玩家，所以改动没有意义，我们需要改动原始的数据。
					targetplayer.ishadLine = true;
					targetplayer.otherLineUser = line.userTwoId;
					userTwo = this.userMgr.get(minLineUser.userId);
					if (userTwo != null) {
						userTwo.ishadLine = true;
						userTwo.otherLineUser = line.userOneId;
					}
					minLineUser.ishadLine = true;
					// console.log("创建一条线");
					roomLine.push(line);
					return;
				}
			}
		}
	}

	//+++++++++++++++linemgr++++++++++++++++//
	//如果玩家ishadline为true 但linedata中却不存在该玩家的线 把该玩家ishadline改为false
	private setIsHadLineFalse(room, user) {
		for (var line of room.roomLine) {
			if (line.userOneId == user.userId || line.userTwoId == user.userId) {
				return;
			}
		}
		user.ishadLine = false;
	}

	/**更改服务器上青蛙位置 */
	public frogchangepoint(targetplayer, point) {
		targetplayer.x = point.x;
		targetplayer.y = point.y;
	}
	public createLines() {
		this.totallinesPool = 0;
		if (this.c == null) {
			console.log('createLines fail!!!!config==null');
			return;
		}
		var numbers = this.c.maxUserCountByRoom * this.c.maxRoomCount * 2 - this.linesPool.length;
		if (numbers <= 0) {
			console.log('createLines fail!!!!num+numbers');
			return;
		}
		//console.log('创建线数目' + numbers);
		//遍历所有道具
		for (var i = 0; i < numbers; ++i) {
			this.createOneLine(i);
		}
	}

	/***初始化线 */
	public restLines() {
		this.cleanRoomLines();

	}
	/**创建一个线 */
	private createOneLine(index) {
		this.linesPool.push({
			userOneId: -1,
			userTwoId: -1,
			type: 0,
			id: index,
			isUsed: false
		});
		this.totallinesPool++;
	}
	/**
	 * 检查连线
	 * 我们来判断一下这些线是否仍然连接
	 */
	private checkLinesAlive(linesPool) {
		for (var m = (linesPool.length - 1); m >= 0; m--) {
			//跳过未使用的线
			if (!linesPool[m].isUsed) {
				continue;
			}
			//判断线是否还存活，不存货则删除
			if (!this.isLineLiving(linesPool[m])) {
				this.recoveryLine(linesPool[m], linesPool);
			}
		}
	}

	public getLineInfo(line) {
		let lineInfo = { isalive: true, ptstart: { x: 0, y: 0 }, ptend: { x: 0, y: 0 } };
		if (line.userOneId < 0 || line.userTwoId < 0) {
			//	console.log("线断了， 一个青蛙UserID 《0");
			lineInfo.isalive = false;
			return lineInfo;

		}
		var userOneInfo = this.userMgr.get(line.userOneId);
		var userTwoInfo = this.userMgr.get(line.userTwoId);
		if (userOneInfo == null || userTwoInfo == null || userOneInfo.death.isDeath || userTwoInfo.death.isDeath) {
			//		console.log("线断了一个青蛙死了");
			lineInfo.isalive = false;
			return lineInfo;

		}
		if (userOneInfo.frogType != userTwoInfo.frogType) {
			//	console.log("线断了 青蛙类型不一样");
			lineInfo.isalive = false;
			return lineInfo;
		}

		if (this.util.getDistance({ x: userOneInfo.x, y: userOneInfo.y }, { x: userTwoInfo.x, y: userTwoInfo.y }) > (userOneInfo.lineLength + userTwoInfo.lineLength)) {
			//	console.log("线断了 第一个人位置" + userOneInfo.x + "|" + userOneInfo.y + "第二个人位置" + userTwoInfo.x + "|" + userTwoInfo.y + "当前距离" + this.util.getDistance({ x: userOneInfo.x, y: userOneInfo.y }, { x: userTwoInfo.x, y: userTwoInfo.y }) + "线长" + (userOneInfo.lineLength + userTwoInfo.lineLength));
			lineInfo.isalive = false;
			return lineInfo;
		}
		lineInfo.ptstart.x = userOneInfo.x;
		lineInfo.ptstart.y = userOneInfo.y;
		lineInfo.ptend.x = userTwoInfo.x;
		lineInfo.ptend.y = userTwoInfo.y;
		return lineInfo;
	}

	private isLineLiving(line) {
		if (line.userOneId < 0 || line.userTwoId < 0) {
			//	console.log("线断了， 一个听蛙UserID 《0");
			return false;
		}
		var userOneInfo = this.userMgr.get(line.userOneId);
		var userTwoInfo = this.userMgr.get(line.userTwoId);
		if (userOneInfo == null || userTwoInfo == null || userOneInfo.death.isDeath || userTwoInfo.death.isDeath) {
			//	console.log("线断了一个青蛙死了");
			return false;
		}
		// if (userOneInfo.propStates.getPropType == 3 || userTwoInfo.propStates.getPropType == 3) {
		// 	return false;
		// }
		if (userOneInfo.frogType != userTwoInfo.frogType) {
			// console.log("线断了 青蛙类型不一样");
			// console.log("frog name"+userOneInfo.name+"NAME2"+userTwoInfo.name+"11111111111111111")
			// console.log("666666666666666666666666666"+userOneInfo.name+userOneInfo.death.isDeath+"///////////"+userTwoInfo.name+userTwoInfo.death.isDeath)
			if (userOneInfo.disconnection_line_time != 1) {
				userOneInfo.disconnection_line = true;
				userOneInfo.disconnection_line_time = Date.now();
			}
			if (userTwoInfo.disconnection_line_time != 1) {
				userTwoInfo.disconnection_line = true
				userTwoInfo.disconnection_line_time = Date.now();
			}
			return false;
		}
		// if (this.util.getDistance({ x: userOneInfo.x, y: userOneInfo.y }, { x: userTwoInfo.x, y: userTwoInfo.y }) > (userOneInfo.lineLength + userTwoInfo.lineLength)) {
		// 	//console.log("线断了 第一个人位置" + userOneInfo.x + "|" + userOneInfo.y + "第二个人位置" + userTwoInfo.x + "|" + userTwoInfo.y + "当前距离" + this.util.getDistance({ x: userOneInfo.x, y: userOneInfo.y }, { x: userTwoInfo.x, y: userTwoInfo.y }) + "线长" + (userOneInfo.lineLength + userTwoInfo.lineLength));
		// 	return this.lineLongerMax(userOneInfo, userTwoInfo);
		// }

		return true;
	}
	/**线超过最大长度 */
	public lineLongerMax(userOneInfo, userTwoInfo) {
		//return true;
		if (userOneInfo.disconnection_line_time != 1) {
			userOneInfo.disconnection_line = true;
			userOneInfo.disconnection_line_time = Date.now();
		}
		if (userTwoInfo.disconnection_line_time != 1) {
			userTwoInfo.disconnection_line = true
			userTwoInfo.disconnection_line_time = Date.now();
		}
		return false;
	}
	public recoveryLine(line, roomLine) {
		if (roomLine == null) {
			//	console.log("逻辑炸弹 recoveryLine");
			return;
		}
		//清空玩家的状态
		var userOneInfo = this.userMgr.get(line.userOneId);
		if (userOneInfo != null) {
			userOneInfo.ishadLine = false;
			userOneInfo.otherLineUser = -1;
			userOneInfo.mistakeRate = 0;
		}
		var userTwoInfo = this.userMgr.get(line.userTwoId);
		if (userTwoInfo != null) {
			userTwoInfo.ishadLine = false;
			userTwoInfo.otherLineUser = -1;
			userTwoInfo.mistakeRate = 0;
		}
		//清空线的状态
		line.isUsed = false;
		line.userOneId = -1;
		line.userTwoId = -1;
		line.type = 0;
		//从房间的线库里面清楚掉这个线
		if (this.util.findIndex(roomLine, line.id) > -1)
			roomLine.splice(this.util.findIndex(roomLine, line.id), 1);
	}
	public getOneLine(useroneid, usertwoid) {



		//获取当前没有使用的道具
		for (var i = 0; i < this.linesPool.length; ++i) {
			if (!this.linesPool[i].isUsed) {
				this.linesPool[i].isUsed = true;
				return this.linesPool[i];
			}
			else {
				if (this.linesPool[i].userOneId == useroneid || this.linesPool[i].userTwoId == useroneid || this.linesPool[i].userOneId == usertwoid || this.linesPool[i].userTwoId == usertwoid) {
					//	console.log("强制回收线");
					return this.linesPool[i];
				}
			}
		}
		console.log("没有线了");
		//没有未使用的则再创建一个
		if (this.c.isproppoolext)
			return this.createExtOneLine();
		else
			return;
	}

	private createExtOneLine() {
		this.totallinesPool++;
		this.linesPool.push({
			userOneId: -1,
			userTwoId: -1,
			type: 0,
			id: this.totallinesPool,
			isUsed: false

		});
		return this.linesPool[this.totallinesPool - 1];
	}

	private cleanRoomLines() {
		for (var i = 0; i < this.linesPool.length; ++i) {
			this.linesPool[i].isUsed = false;
			this.linesPool[i].userOneId = -1;
			this.linesPool[i].userTwoId = -1;
			this.linesPool[i].type = 0;
		}
		AIServer.getInstance().roomInfo.roomLine = [];
	}
	private gettotallinesPool() {
		return this.totallinesPool;
	}
	public checkIsOnALine(something, usrend, usrstart) {
		/**点到线的距离 */
		var pointToLineLength = this.util.getPointToLineDistance(usrend, usrstart, something);

		return pointToLineLength < 50 ? true : false;
	}
	public checkLineIsOnALine(something, usrend, usrstart) {
		/**点到线的距离 */
		var pointToLineLength = this.util.getPointToLineDistance(usrend, usrstart, something);
		//  console.log("pointToLineLength="+pointToLineLength);
		return pointToLineLength < 50 ? true : false;
	}

	public getUserLine(lines, user) {
		if (lines == null || user == null)
			return null;

		for (var m = (lines.length - 1); m >= 0; m--) {

			//跳过未使用的线
			if (!lines[m].isUsed) {
				continue;
			}
			/**判断是否有玩家的线 */
			if (lines[m].userOneId == user.userId || lines[m].userTwoId == user.userId) {
				return lines[m];
			}



		}
		return null;
	}


	//如果玩家连线  从lineData中删除玩家所在的线
	public deleteLineFromPlayer(room, user) {
		if (!user.ishadLine)
			return;

		//获取线上另外一个玩家，将其的连线状态去除


		var id = user.userId;
		var index = null;
		for (var i = 0; i < room.roomLine.length; i++) {
			if (room.roomLine[i].userOneId == id || room.roomLine[i].userTwoId == id) {
				index = i;
				break;
			}
		}



		if (index != null) {
			var userOneInfo = this.userMgr.get(room.roomLine[index].userOneId);
			if (userOneInfo != null) {
				userOneInfo.ishadLine = false;

				userOneInfo.otherLineUser = -1;

				userOneInfo.mistakeRate = 0;
			}
			var userTwoInfo = this.userMgr.get(room.roomLine[index].userTwoId);
			if (userTwoInfo != null) {
				userTwoInfo.ishadLine = false;

				userTwoInfo.otherLineUser = -1;

				userTwoInfo.mistakeRate = 0;
			}

			room.roomLine.splice(index, 1);
		} else {
			user.ishadLine = false;
			console.log("玩家身上有线但在roomLine中没有找到对应的线");
		}
	}

	private calulateP0tmp = new egret.Point(0, 0);
	private calulateP1tmp = new egret.Point(0, 0);
	/**计算弹开距离 */
	public calulatePopDir1(playOne, playerTwo) {
		this.calulateP0tmp.setTo(playOne.x, playOne.y);
		this.calulateP1tmp.setTo(playerTwo.x, playerTwo.y);

		var dir0: any = this.calulateP0tmp.subtract(this.calulateP1tmp);
		dir0.normalize(60);
		let targePoint0 = this.calulateP0tmp.add(dir0)
		return targePoint0;
	}

	private calulatePopDirPoint = new egret.Point();
	private P0 = new egret.Point();
	//private P1 = new egret.Point();
	/**计算弹开距离 */
	public calulatePopDir(playOne, playerTwo, playOneLv, playerTwoLv) {
		let P2 = this.P0.setTo(playOne.x, playOne.y);
		//let P3 = this.P1.setTo(playerTwo.x, playerTwo.y);
		//var dir0: any = P0.subtract(P1);
		var dir0 = this.calulatePopDirPoint.setTo(playOne.x - playerTwo.x, playOne.y - playerTwo.y);
		var lv = playOneLv - playerTwoLv;
		if (lv == 0) {
			//this.calulatePopDirPoint.normalize(60);
			dir0.normalize(60);
		}
		if (lv == 1) {
			//this.calulatePopDirPoint.normalize(50);
			dir0.normalize(50);
		}
		if (lv == 2) {
			//this.calulatePopDirPoint.normalize(40);.
			dir0.normalize(40);
		}
		if (lv == 3) {
			//this.calulatePopDirPoint.normalize(20);
			dir0.normalize(20);
		}
		if (lv == -1) {
			//this.calulatePopDirPoint.normalize(70);
			dir0.normalize(70);
		}
		if (lv == -2) {
			//this.calulatePopDirPoint.normalize(80);
			dir0.normalize(80);
		}
		if (lv == -3) {
			//this.calulatePopDirPoint.normalize(100);
			dir0.normalize(100);
		}
		//let targePoint0 =this.calulatePopDirPoint.setTo(this.calulatePopDirPoint.x + playOne.x, this.calulatePopDirPoint.y + playOne.y);
	//	let targePoint0 = P2.add(dir0);
		return {x:P2.x+dir0.x,y:P2.y+dir0.y};
	}
	/**获取弹开动画 */
	public getflicktween(point, player) {
		if (webNetworkMananger.getInstance().gameSceneRec != null) {
			if (webNetworkMananger.getInstance().gameSceneRec.m_createAllFrogs != null) {
				var frog = webNetworkMananger.getInstance().gameSceneRec.m_createAllFrogs.findFrogById(player.userId)
				if (frog != null) {
					if (frog.tweenOver) {
						if (player.isAI) {
							frog.flicktweenAI(point);
						}
						else {
							frog.flicktween(point);
						}
					}
				}
			}
		}
	}
}
